package com.pactera.asmp.server.utils;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.pactera.asmp.server.common.logprint.utils.StringUtils;
import com.pactera.asmp.server.service.maccode.*;
import com.pactera.asmp.server.vo.AutherUserInfo;
import com.pactera.asmp.server.vo.LicenseInfo;
import com.pactera.asmp.server.vo.MachineNo;
import org.apache.commons.codec.binary.Base64;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;
import java.util.List;

//@Component
public class AsmpAuthUtil {

    private static Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);

    private static boolean AUTH_RESULT = false;

//    private static ApplicationContext applicationContext;

    public static boolean verifyAuth(){
        try{
            String path = System.getProperty("auth.user.filepath");
            if(StringUtils.isEmpty(path)){
                path = System.getProperty("user.dir") + File.separator+"license";
            }
            //读license
            File file = new File(path);
            if(!file.exists()){
                logger.error("license file not found");
                return false;
            }
            byte[] datas = getByteByFile(file);
            String json = new String(datas,"UTF-8");
            logger.info(json);
            LicenseInfo license = JSONObject.parseObject(json,LicenseInfo.class);
            //解密
            //Base64
            byte[] decDatas = RSAUtil.decryptRSAByPub(Base64.decodeBase64(license.getBussiness()),
                    true,"UTF-8", license.getPublicKey());
            //验签
            boolean isOk = RSAUtil.verifySign(Base64.decodeBase64(license.getBussiness()),
                    license.getPublicKey(), license.getSign());
            if(!isOk){
                AUTH_RESULT = false;
                logger.error("sign verify result:"+isOk);
                return false;
            }
            AutherUserInfo autherUserInfo = JSONObject.parseObject(new String(decDatas,"UTF-8"), AutherUserInfo.class);
            logger.info("sign:"+isOk+",data:" + JSONObject.toJSON(autherUserInfo));
            //比较系统时间
            Date startDate = DateUtil.parseStrToDate(autherUserInfo.getStartDate(),DateUtil.DATE_FORMAT_YY_MM_DD);
            Date endDate = DateUtil.parseStrToDate(autherUserInfo.getEndDate(),DateUtil.DATE_FORMAT_YY_MM_DD);
            Date now = getNetworkTime();
            if(now.before(startDate)){
                logger.error("startdate is after now,startDate={}", autherUserInfo.getStartDate());
                return false;
            }
            if(now.after(endDate)){
                logger.error("enddate is before now,endDate={}", autherUserInfo.getEndDate());
                return false;
            }
            //比较machineCode;
            List<MachineNo> machineNos = autherUserInfo.getMachineNos();
            String sysMacCode = getSysMachineCode(autherUserInfo.getSysType());
            boolean b = machineNos.stream().anyMatch(e -> org.apache.commons.lang3.StringUtils.equals(e.getMachineNo(), sysMacCode));
            if(CollectionUtil.isNotEmpty(machineNos)) {
                //非空需要比较macCode
                if (!b) {
                    logger.error("machineCode is verify false,machineNo={}, current No={}", autherUserInfo.getMachineNos(), sysMacCode);
                    return false;
                }
            }else{
                logger.warn("license macCode not to bind system!");
            }
            AUTH_RESULT = true;
            return true;
        }catch (Exception e){
            logger.error("",e);
        }
        return false;
    }

    private static String getSysMachineCode(String sysType){
        if("1".equals(sysType)){
            SequenceService ss = new WindowsSequenceService();
            return ss.getSequence();
        }
        if("2".equals(sysType)){
            SequenceService ss = new LinuxSequenceService();
            return ss.getSequence();
        }
        if("3".equals(sysType)){
            SequenceService ss = new MacSequenceService();
            return ss.getSequence();
        }
        if("4".equals(sysType)){
            SequenceService ss = new SolarisSequenceService();
            return ss.getSequence();
        }
        if(StringUtils.isEmpty(sysType)){
            SequenceService ss = new LinuxSequenceService();
            return ss.getSequence();
        }
        return "";
    }

    public static boolean getAuthResult(){
        return AUTH_RESULT;
    }

    private static byte[] getByteByFile(File file){
        FileInputStream in = null;
        try {
            // 一次读多个字节
            byte[] tempbytes = new byte[10240];
            int byteread = 0;
            in = new FileInputStream(file);
            logger.info("当前字节输入流中的字节数为:" + in.available());
            // 读入多个字节到字节数组中，byteread为一次读入的字节数
            while ((byteread = in.read(tempbytes)) != -1) {
                //System.out.write(tempbytes, 0, byteread);
            }
            return tempbytes;
        } catch (Exception e1) {
            logger.error("", e1);
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e1) {
                }
            }
        }
        return null;
    }

    /*
     * 获取当前网络时间
     */
    private static Date getNetworkTime() {
        try {
            URL url=new URL("https://www.baidu.com");
            URLConnection conn=url.openConnection();
            conn.connect();
            long dateL=conn.getDate();

            return new Date(dateL);
        }catch (Exception e) {
            logger.error("", e);
        }
        return new Date();
    }
}
